# 单纯的重复不是迭代
"""
i= 0
while True:
    print(i)
"""
# 迭代是一个重复的过程，每一次重复都是基于上一次的结果而来
"""
L = ['a','b','c']
i = 0
while i < len(L):
    print(i)
    print(L[i])
    i+=1
#  哪些数据类型需要这样迭代取值?
tuple1 = (1,2,3)
str1 = "123"
set1 = {1,2,3}
dict1 = {"姓名":"王长帅不是很帅的长随哎","年龄":39}
"""
# 只对序列类型有效果
# 所以我们需要一种不依赖索引取值的方式
# 迭代器提供了一种通用的且不依赖于索引的迭代取值方式的功能

# 可迭代对象
#一︰可迭代的对象iterable:但凡内置有_iter__方法的对象
# 都称之为可迭代的对象
#因为_iter_方法这个方法可以生成迭代器
#作者是个天才，每个需要取值的都加了_iter__方法
"""
a = 1
# a.__iter__() #没有
b = 1.1
# b.__iter__() 没有
c = 'hello'
c.__iter__()
d = ['a','c']
d.__iter__()
g = {1,2,3}
g.__iter__()
"""

# 迭代器
# iter和next被称为迭代器协议，iter是创建迭代器，next是访问下一次的元素
# 如果访问都结束了，再进行下一个访问时，会报错
"""
set1 = {1,2,3}
iter_set = set1.__iter__() # 创建了一个迭代器
print(iter_set.__next__()) #访问下一个 1
print(iter_set.__next__()) #访问下一个 2
print(iter_set.__next__()) #访问下一个 3
# print(iter_set.__next__()) #访问下一个 :StopIteration

list1 = [1,2,3]
iter_list = list1.__iter__() # 创建列表迭代器
print(iter_list.__next__()) # 1
print(iter_list.__next__()) # 2
print(iter_list.__next__()) # 3
print(iter_list.__next__()) # StopIteration
"""

# 误区
l1 = [1,2,3]
#基于新的迭代器l1.__iter_()
# 生成了一个迭代器，并且取了第一个值
"""
print(l1.__iter__().__next__())#1
# 又生成了一个迭代器，并且取了第一个值
print(l1.__iter__().__next__())
# 又生成了一个迭代器，并且取了第一个值
print(l1.__iter__().__next__())

l2 = [1,2,3]
# 创建一个新的迭代器，然后再去迭代
list_l2_iter = l2.__iter__()
print(list_l2_iter.__next__())#1
print(list_l2_iter.__next__())#2
print(list_l2_iter.__next__())#3
"""
# range(1,30).__iter__()
"""
l = [1,2,3]
for k in l:
    print(k)
"""
# 迭代器总结
"""
obj_iter = range(1,10)
# print(obj_iter) # range(1, 10)
# 将range创建成迭代器对象
obj_next = obj_iter.__iter__()
# 通过创建的迭代器对象，访问下一个元素
print(obj_next.__next__()) # 1
print(obj_next.__next__()) # 2
print(obj_next.__next__()) # 3
# 问题：
print('迭代器的for循环下了三个鸡蛋的母鸡')
for i in obj_next:
    # 是1还是4开始
    print(i)
print('再次')

for i in obj_next:
    print(i)
print('可迭代对象的for循环没下蛋的母鸡')
for i in obj_iter:
    print(i)
for i in obj_iter:
    print(i)
"""

# 生成器
# 大前提:生成器就是一种自定义的迭代器，本质就是迭代器
# 但凡函数内包含yield关键字，调用函数不会执行函数体代码
# 会得到一个返回值，该返回值就是生成器对象
def g():
    a = 1
    while True:
        yield a # return 第一次的时候，返回1  第二次的时候，返回 2  第三次返回3
        a += 1 # a+=1 a+=1
#next函数可用于引起生成器/迭代器的下一次生成/迭代。其返回值就是下一个生成的值。

# 通过 next(generator) 这一方式，可以获得一系列值。
a = g() # 通过g函数 创建对象a
# print(g()) # <generator object g at 0x02244730>
print(a.__next__()) # 1
print(a.__next__()) # 2



